﻿// ———————————————————————–
// <copyright file="ResourceDefinitionType.cs" company="The MITRE Corporation">
//    Copyright (c) 2014 The MITRE Corporation. All rights reserved.
//    Licensed under the Apache License, Version 2.0 (the "License");
//    you may not use this file except in compliance with the License.
//    You may obtain a copy of the License at
//    http://www.apache.org/licenses/LICENSE-2.0
//    Unless required by applicable law or agreed to in writing, software
//    distributed under the License is distributed on an "AS IS" BASIS,
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//    See the License for the specific language governing permissions and
//    limitations under the License.
// </copyright>
// ———————————————————————–
/////////////////////////////////////////////////////////////////////////////////////////////////
// ResourceDefinitionType.cs:
//
// 
//
// Project: IC.NET - CAD Library
// Author:  Jim Cronin - MITRE
/////////////////////////////////////////////////////////////////////////////////////////////////

// Copyright (c) 2014 The MITRE Corporation. All rights reserved.
//
// NOTICE
// This software was produced for the U. S. Government
// under Contract No. FA8721-09-C-0001, and is
// subject to the Rights in Noncommercial Computer Software
// and Noncommercial Computer Software Documentation Clause
// (DFARS) 252.227-7014 (JUN 1995)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml;

namespace EDXLSharp.FEMARTLT
{
  public abstract class ResourceDefinitionType : Definition
  {
    public ICollection<string> SupportingCoreCapabilities;
    public string Description;
    public string Category;
    public string Kind;
    public string OverallFunction;
    public string CompositionOrdering;
    public ICollection<ResourceCapability> Capabilities;
    public ICollection<ResourceComment> Comments;
    public ICollection<ResourceReference> References;
    public ICollection<ResourceNote> Notes;

    public ResourceDefinitionType()
      : base()
    {
      SupportingCoreCapabilities = new List<string>();
      Capabilities = new List<ResourceCapability>();
      Comments = new List<ResourceComment>();
      References = new List<ResourceReference>();
      Notes = new List<ResourceNote>();
    }

    /// <summary>
    /// Writes this Object to an inline XML Document
    /// </summary>
    /// <param name="xwriter">Valid XMLWriter</param>
    /// <exception cref="System.ArgumentNullException">Thrown if xwriter is null</exception>
    /// <exception cref="EDXLSharp.ValidationException">Thrown if the object fails to validate</exception>
    public override void WriteXML(XmlWriter xwriter)
    {
      if (xwriter == null)
      {
        throw new ArgumentNullException("xwriter");
      }

      this.Validate();

      xwriter.WriteStartElement(ElementPrefix, ElementName, ElementNamespace);
      WriteInnerXML(xwriter);
      xwriter.WriteEndElement();
    }

    protected override void WriteInnerXML(XmlWriter xwriter)
    {
      base.WriteInnerXML(xwriter);

      if (SupportingCoreCapabilities.Any())
      {
        xwriter.WriteStartElement("SupportingCoreCapabilities", EDXLConstants.FEMARTLTNamespace);
        foreach (string coreCap in SupportingCoreCapabilities)
        {
          xwriter.WriteStartElement("ResourceSupportingCoreCapability", EDXLConstants.FEMARTLTNamespace);
          xwriter.WriteElementString("Name", EDXLConstants.FEMARTLTNamespace, coreCap);
          xwriter.WriteEndElement();
        }
        xwriter.WriteEndElement();
      }
      if (!string.IsNullOrEmpty(Description))
      {
        xwriter.WriteElementString("Description", EDXLConstants.FEMARTLTNamespace, Description);
      }
      if (!string.IsNullOrEmpty(Category))
      {
        xwriter.WriteElementString("Category", EDXLConstants.FEMARTLTNamespace, Category);
      }
      if (!string.IsNullOrEmpty(Kind))
      {
        xwriter.WriteElementString("Kind", EDXLConstants.FEMARTLTNamespace, Kind);
      }
      if (!string.IsNullOrEmpty(OverallFunction))
      {
        xwriter.WriteElementString("OverallFunction", EDXLConstants.FEMARTLTNamespace, OverallFunction);
      }
      if (!string.IsNullOrEmpty(CompositionOrdering))
      {
        xwriter.WriteElementString("CompositionOrdering", EDXLConstants.FEMARTLTNamespace, CompositionOrdering);
      }
      if (Capabilities.Any())
      {
        xwriter.WriteStartElement("Capabilities", EDXLConstants.FEMARTLTNamespace);
        foreach (ResourceCapability rcap in Capabilities)
        {
          rcap.WriteXML(xwriter);
        }
        xwriter.WriteEndElement();
      }
      if (Comments.Any())
      {
        xwriter.WriteStartElement("Comments", EDXLConstants.FEMARTLTNamespace);
        foreach (ResourceComment comment in Comments)
        {
          comment.WriteXML(xwriter);
        }
        xwriter.WriteEndElement();
      }
      if (References.Any())
      {
        xwriter.WriteStartElement("References", EDXLConstants.FEMARTLTNamespace);
        foreach (ResourceReference reference in References)
        {
          reference.WriteXML(xwriter);
        }
        xwriter.WriteEndElement();
      }
      if (Notes.Any())
      {
        xwriter.WriteStartElement("Notes", EDXLConstants.FEMARTLTNamespace);
        foreach (ResourceNote note in Notes)
        {
          note.WriteXML(xwriter);
        }
        xwriter.WriteEndElement();
      }
    }

    /// <summary>
    /// Reads this Object's values from an XML nodelist
    /// </summary>
    /// <param name="rootnode">root XML Node of the Object element</param>
    /// <exception cref="System.ArgumentNullException">Thrown if rootnode is null</exception>
    /// <exception cref="System.ArgumentException">Thrown if the rootnode is not the correct type</exception>
    /// <exception cref="EDXLSharp.ValidationException">Thrown if the object fails to validate</exception>
    public override void ReadXML(XmlNode rootnode)
    {
      if (rootnode == null)
      {
        throw new ArgumentNullException("rootnode");
      }

      if (rootnode.LocalName != ElementName)
      {
        throw new ArgumentException("Unexpected element " + rootnode.LocalName + " instead of " + ElementName);
      }

      foreach (XmlNode node in rootnode.ChildNodes)
      {
        ReadNode(node);
      }

      this.Validate();
    }

    protected override void ReadNode(XmlNode node)
    {
      switch (node.LocalName)
      {
        case "SupportingCoreCapabilities":
          foreach (XmlNode cap in node.ChildNodes)
          {
            SupportingCoreCapabilities.Add(cap.FirstChild.InnerText);
          }
          break;
        case "Description":
          Description = node.InnerText;
          break;
        case "Category":
          Category = node.InnerText;
          break;
        case "Kind":
          Kind = node.InnerText;
          break;
        case "OverallFunction":
          OverallFunction = node.InnerText;
          break;
        case "CompositionOrdering":
          CompositionOrdering = node.InnerText;
          break;
        case "Capabilities":
          foreach (XmlNode capNode in node.ChildNodes)
          {
            ResourceCapability rcap = new ResourceCapability();
            rcap.ReadXML(capNode);
            Capabilities.Add(rcap);
          }
          break;
        case "Comments":
          foreach (XmlNode commentNode in node.ChildNodes)
          {
            ResourceComment comment = new ResourceComment();
            comment.ReadXML(commentNode);
            Comments.Add(comment);
          }
          break;
        case "References":
          foreach (XmlNode referenceNode in node.ChildNodes)
          {
            ResourceReference rref = new ResourceReference();
            rref.ReadXML(referenceNode);
            References.Add(rref);
          }
          break;
        case "Notes":
          foreach (XmlNode noteNode in node.ChildNodes)
          {
            ResourceNote note = new ResourceNote();
            note.ReadXML(noteNode);
            Notes.Add(note);
          }
          break;
        default:
          base.ReadNode(node);
          break;
      }
    }

    /// <summary>
    /// Validates This Message element For Required Values and Conformance
    /// </summary>
    /// <exception cref="EDXLSharp.ValidationException">Thrown if the object fails to validate</exception>
    public override void Validate()
    {
      if (Capabilities != null)
      {
        foreach (ResourceCapability capability in Capabilities)
        {
          capability.Validate();
        }
      }
      if (Comments != null)
      {
        foreach (ResourceComment comment in Comments)
        {
          comment.Validate();
        }
      }
      if (References != null)
      {
        foreach (ResourceReference reference in References)
        {
          reference.Validate();
        }
      }
      if (Notes != null)
      {
        foreach (ResourceNote note in Notes)
        {
          note.Validate();
        }
      }
    }
  }
}